/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.meta.rpc.upgrade;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.je.common.base.DynaBean;
import com.je.common.base.entity.extjs.DbModel;
import com.je.common.base.exception.PlatformException;
import com.je.common.base.exception.PlatformExceptionEnum;
import com.je.common.base.func.funcPerm.ControlFieldAuthVo;
import com.je.common.base.func.funcPerm.FieldAuth.FieldAuthVo;
import com.je.common.base.func.funcPerm.FuncDataPermVo;
import com.je.common.base.func.funcPerm.dictionaryAuth.DictionaryAuthVo;
import com.je.common.base.func.funcPerm.fastAuth.FastAuthVo;
import com.je.common.base.func.funcPerm.roleSqlAuth.RoleSqlAuthVo;
import com.je.common.base.service.CommonService;
import com.je.common.base.service.MetaService;
import com.je.common.base.service.rpc.AbstractUpgradeModulePackageRpcServiceImpl;
import com.je.common.base.service.rpc.UpgradeModulePackageRpcService;
import com.je.common.base.upgrade.PackageResult;
import com.je.common.base.upgrade.UpgradeResourcesEnum;
import com.je.common.base.util.MessageUtils;
import com.je.common.base.util.StringUtil;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.meta.constant.FuncDataPermCons;
import com.je.meta.service.MetaStaticizeService;
import com.je.meta.service.func.FuncPermService;
import com.je.meta.service.table.MetaTableService;
import com.je.meta.service.upgrade.impl.AbstractUpgradeMetaDate;
import com.je.meta.service.upgrade.impl.UpgradeMeteDateFactory;
import com.je.meta.util.enumUtil.FuncTypeEnum;
import com.je.meta.util.enumUtil.TableTypeEnum;
import com.je.rbac.rpc.PermissionRpcService;
import com.je.servicecomb.RpcSchemaFactory;
import org.apache.servicecomb.provider.pojo.RpcSchema;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

import static com.je.servicecomb.JECloud.PRODUCT_CORE_META;

@RpcSchema(schemaId = "upgradeModulePackageRpcService")
public class UpgradeModulePackageRpcServiceImpl extends AbstractUpgradeModulePackageRpcServiceImpl implements UpgradeModulePackageRpcService {

    private static final Logger logger = LoggerFactory.getLogger(UpgradeModulePackageRpcServiceImpl.class);

    private static final String[] UPDATE_TABLE_TYPE = new String[]{TableTypeEnum.PT.getValue(), TableTypeEnum.TREE.getValue()};

    @Autowired
    private MetaService metaService;


    @Autowired
    private CommonService commonService;

    @Autowired
    private MetaTableService tableService;

    @Autowired
    private FuncPermService funcPermService;

    @Autowired
    private UpgradelogRpcService upgradelogRpcService;

    @Autowired
    private MetaStaticizeService metaStaticizeService;

    @Autowired
    private PermissionRpcService permissionRpcService;

    @Override
    public String doCheck(PackageResult packageResult) {
        List<String> packageTableCodes = new ArrayList<>();
        DynaBean product = packageResult.getProduct();
        String productCode = product.getStr("PRODUCT_CODE");
        /**
         * 资源表
         * 1.安装包里的表存在数据库，但没被平台管理
         * 2.如果有子表，需检查是否存在主表，如不存在，则抛异常
         * 3.检查创建视图的表是否都存在
         */
        List<DynaBean> productTables = packageResult.getProductTables();
        if (productTables != null && productTables.size() > 0) {
            for (DynaBean dynaBean : productTables) {
                packageTableCodes.add(dynaBean.getStr("RESOURCETABLE_TABLECODE"));
            }
            for (DynaBean table : productTables) {

                if (!TableTypeEnum.VIEW.getValue().equals(table.getStr("RESOURCETABLE_TYPE"))) {
                    /**
                     *检查主子表
                     */
                    String parentTableCodes = table.getStr("RESOURCETABLE_PARENTTABLECODES");
                    if (StringUtil.isNotEmpty(parentTableCodes)) {
                        for (String parentTableCode : parentTableCodes.split(",")) {
                            boolean result = checkTableExists(packageTableCodes, parentTableCode);
                            if (!result) {
                                return MessageUtils.getMessage("upgrade.table.not.found.parentTable", table.getStr("RESOURCETABLE_TABLECODE"), parentTableCode);
                            }
                        }
                    }
                } else {
                    /**
                     * 检查创建视图的表是否都存在
                     */
                    String RESOURCETABLE_COORDINATE = table.getStr("RESOURCETABLE_COORDINATE");
                    if (StringUtil.isNotEmpty(RESOURCETABLE_COORDINATE)) {
                        JSONArray jsonArray = JSONArray.parseArray(RESOURCETABLE_COORDINATE);
                        if (jsonArray.size() > 0) {
                            for (int i = 0; i < jsonArray.size(); i++) {
                                JSONObject jsonObject = jsonArray.getJSONObject(i);
                                boolean result = checkTableExists(packageTableCodes, jsonObject.getString("tableCode"));
                                if (!result) {
                                    return MessageUtils.getMessage("upgrade.view.not.found.baseTable", table.getStr("RESOURCETABLE_TABLECODE"), jsonObject.getString("tableCode"));
                                }
                            }
                        }
                    }
                }
            }
        }
        /**
         * 检查创建功能的表是否存在：检查升级包和本地数据库
         */
        List<DynaBean> funcs = packageResult.getProductFunctions();
        if (funcs != null && funcs.size() > 0) {
            String result = checkFuncionsTableExists(funcs, packageTableCodes, productCode);
            if (StringUtil.isNotEmpty(result)) {
                return result;
            }
        }
        /**
         * 检验业务数据的表是否存在
         */
        Map<String, List<DynaBean>> businessDataMap = packageResult.getBusinessDataMap();
        if (businessDataMap != null && businessDataMap.size() > 0) {
            Set<String> set = businessDataMap.keySet();
            for (String tableCode : set) {
                boolean result = checkTableExists(packageTableCodes, tableCode);
                if (!result) {
                    return MessageUtils.getMessage("upgrade.businessData.table.not.found", tableCode);
                }
            }
        }
        return null;
    }

    private String checkFuncionsTableExists(List<DynaBean> funcs, List<String> packageTableCodes, String productCode) {
        for (DynaBean func : funcs) {
            if (!"MODEL".equals(func.getStr("FUNCINFO_FUNCTYPE")) && !"SYSTEM".equals(func.getStr("FUNCINFO_FUNCTYPE"))) {
                boolean result = checkTableExists(packageTableCodes, func.getStr("FUNCINFO_TABLENAME"));
                if (!result) {
                    return MessageUtils.getMessage("upgrade.function.table.not.found", func.getStr("FUNCINFO_FUNCNAME"), func.getStr("FUNCINFO_TABLENAME"));
                }
            }
        }
        return null;
    }


    public boolean checkTableExists(List<String> packageTableCodes, String tableCode) {
        boolean isInPackage = false;
        for (String packageTableCode : packageTableCodes) {
            if (packageTableCode.toUpperCase().equals(tableCode.toUpperCase())) {
                isInPackage = true;
                break;
            }
        }
        if (isInPackage) {
            return true;
        }
        DynaBean parentTable = metaService.selectOne("JE_CORE_RESOURCETABLE",
                ConditionsWrapper.builder().eq("RESOURCETABLE_TABLECODE", tableCode));
        if (parentTable == null) {
            parentTable = metaService.selectOne("JE_CORE_RESOURCETABLE",
                    ConditionsWrapper.builder().eq("RESOURCETABLE_TABLECODE", tableCode.toUpperCase()));
            if (parentTable == null) {
                return false;
            }
        }
        return true;
    }

    @Override
    public PackageResult packageModule(DynaBean upgradeBean) {
        PackageResult packageResult = new PackageResult();
        String productId = upgradeBean.getStr("SY_PRODUCT_ID");
        packageResult.setProduct(packageProduct(productId));

        for (String key : UpgradeResourcesEnum.getAllValue().keySet()) {
            UpgradeResourcesEnum upgradeResourcesEnum = UpgradeResourcesEnum.getUpgradeResourcesEnumByType(key);
            if (upgradeResourcesEnum.getPackProduct().equals("meta")) {
                UpgradeMeteDateFactory.getUpgradeMeteDateServiceByType(upgradeResourcesEnum.getType()).packUpgradeMetaDate(packageResult, upgradeBean);
            }
        }

        packageResult.setUpgrade(upgradeBean);
        return packageResult;
    }

    @Override
    public String installModule(PackageResult packageResult) {
        //产品信息
        DynaBean product = packageResult.getProduct();
        String upgradeInstallId = packageResult.getInstallPackageId();
        installProduct(product);
        //资源表
        if (packageResult.getProductTables() != null) {
            installTable(upgradeInstallId, packageResult.getProductTables(), product.getStr("PRODUCT_CODE"));
        }
        //功能
        if (packageResult.getProductFunctions() != null) {
            installFunction(upgradeInstallId, packageResult.getProductFunctions());
        }

        for (String key : UpgradeResourcesEnum.getAllValue().keySet()) {
            UpgradeResourcesEnum upgradeResourcesEnum = UpgradeResourcesEnum.getUpgradeResourcesEnumByType(key);
            if (!upgradeResourcesEnum.getPackProduct().equals("meta")) {
                continue;
            }
            //table和func在上面处理了，在这里过滤掉 业务数据处理也过滤掉，下面处理了
            if (upgradeResourcesEnum == UpgradeResourcesEnum.TABLE || upgradeResourcesEnum == UpgradeResourcesEnum.FUNC ||
                    upgradeResourcesEnum == UpgradeResourcesEnum.BUSINESS) {
                continue;
            }
            AbstractUpgradeMetaDate abstractUpgradeMetaDate = UpgradeMeteDateFactory.getUpgradeMeteDateServiceByType(upgradeResourcesEnum.getType());
            List<DynaBean> necessaryData = abstractUpgradeMetaDate.extractNecessaryData(packageResult);
            if (necessaryData == null) {
                continue;
            }
            abstractUpgradeMetaDate.installUpgradeMetaDate(upgradeInstallId, necessaryData, product.getStr("PRODUCT_CODE"), null);
        }

        if (packageResult.getBusinessDataMap() != null) {
            Map<String, List<DynaBean>> businessDataMap = packageResult.getBusinessDataMap();
            Map<String, List<DynaBean>> map = new LinkedHashMap<>();
            List<DynaBean> list = packageResult.getUpgradeResources();
            if (list.size() == 0) {
                map = businessDataMap;
            } else {
                for (DynaBean bean : list) {
                    if (bean.getStr("UPGRADERESOURCE_TYPE_CODE").equals(UpgradeResourcesEnum.BUSINESS.getType())) {
                        DynaBean table = metaService.selectOneByPk("JE_CORE_RESOURCETABLE", bean.getStr("UPGRADERESOURCE_CONTENT_CODE"));
                        if (table != null) {
                            String tableCode = table.getStr("RESOURCETABLE_TABLECODE");
                            map.put(tableCode, businessDataMap.get(tableCode));
                        }
                    }
                }
            }
            if (map != null && map.size() > 0) {
                if (PRODUCT_CORE_META.equals(product.getStr("PRODUCT_CODE"))) {
                    installBusinessData(map);
                } else {
                    try {
                        UpgradeModulePackageRpcService upgradeModulePackageRpcService = RpcSchemaFactory.getRemoteProvierClazz(product.getStr("PRODUCT_CODE"),
                                "upgradeModulePackageRpcService", UpgradeModulePackageRpcService.class);
                        upgradeModulePackageRpcService.installBusinessData(map);
                    } catch (Exception e) {
                        throw new PlatformException("升级业务数据失败，请看日志信息！", PlatformExceptionEnum.UNKOWN_ERROR);
                    }
                }
            }
        }
        return null;
    }

    private DynaBean packageProduct(String productId) {
        DynaBean productBean = metaService.selectOne("JE_PRODUCT_MANAGE", ConditionsWrapper.builder().eq("JE_PRODUCT_MANAGE_ID", productId));
        return productBean;
    }

    @Transactional
    public String installProduct(DynaBean product) {
        // String code = product.getStr("PRODUCT_CODE");
        String productId = product.getStr("JE_PRODUCT_MANAGE_ID");
        DynaBean dynaBean = metaService.selectOne("JE_PRODUCT_MANAGE",
                ConditionsWrapper.builder().eq("JE_PRODUCT_MANAGE_ID", productId));
        product.table("JE_PRODUCT_MANAGE");
        if (dynaBean == null) {
            commonService.buildModelCreateInfo(product);
            metaService.insert(product);
        } else {
            product.setStr("PRODUCT_DEVELOPER", dynaBean.getStr("PRODUCT_DEVELOPER"));
            product.setStr("PRODUCT_DEVELOPER_ID", dynaBean.getStr("PRODUCT_DEVELOPER_ID"));
            commonService.buildModelModifyInfo(product);
            metaService.update(product, ConditionsWrapper.builder().eq("JE_PRODUCT_MANAGE_ID", productId));
        }
        return null;
    }

    @Transactional
    public String installFunction(String upgradeInstallId, List<DynaBean> funcBeanList) {
        for (DynaBean func : funcBeanList) {
            func.table("JE_CORE_FUNCINFO");
            String code = func.getStr("FUNCINFO_FUNCCODE");
            DynaBean funcDB = metaService.selectOne("JE_CORE_FUNCINFO",
                    ConditionsWrapper.builder().eq("FUNCINFO_FUNCCODE", code));
            /**
             * 目前树形表都是内联外键，导致删除父级时子级全部自动删除
             * 1.现修改为功能再目标系统若存在，则更新,不会删除
             */

            String parentId = func.getStr("SY_PARENT");
            DynaBean parentBean = metaService.selectOneByPk("JE_CORE_FUNCINFO", parentId);
            if (parentBean == null) {
                throw new RuntimeException(func.getStr("FUNCINFO_FUNCNAME") + "的父级没有找到，请检查");
            }

            try {
                if (funcDB != null) {
                    deleteChildTableDataByFuncId(funcDB.getStr("JE_CORE_FUNCINFO_ID"));
                    commonService.buildModelModifyInfo(func);
                    metaService.update(func, ConditionsWrapper.builder().eq("FUNCINFO_FUNCCODE", code));
                } else {
                    commonService.buildModelCreateInfo(func);
                    metaService.insert(func);
                }
            } catch (Exception e) {
                StringBuffer errorString = new StringBuffer();
                if (funcDB == null) {
                    errorString.append("升级包功能code：" + func.getStr("FUNCINFO_FUNCCODE"));
                    errorString.append("升级包功能id：" + func.getStr("JE_CORE_FUNCINFO_ID"));
                } else {
                    errorString.append("------------升级包功能code：" + func.getStr("FUNCINFO_FUNCCODE") + "当前资源功能code：" + funcDB.getStr("FUNCINFO_FUNCCODE"));
                    errorString.append("------------升级包功能id：" + func.getStr("JE_CORE_FUNCINFO_ID") + "当前资源功能id：" + funcDB.getStr("JE_CORE_FUNCINFO_ID"));
                }
                throw new RuntimeException("升级资源表报错：" + errorString.toString());
            }


            //列表字段
            List<Map<String, Object>> columns = (List<Map<String, Object>>) func.get("columns");
            if (columns != null && columns.size() > 0) {
                batchInsert(columns, "JE_CORE_RESOURCECOLUMN");
            }
            //表单字段
            List<Map<String, Object>> fields = (List<Map<String, Object>>) func.get("fields");
            if (fields != null && fields.size() > 0) {
                batchInsert(fields, "JE_CORE_RESOURCEFIELD");
            }
            //按钮
            List<Map<String, Object>> buttons = (List<Map<String, Object>>) func.get("buttons");
            if (buttons != null && buttons.size() > 0) {
                batchInsert(buttons, "JE_CORE_RESOURCEBUTTON");
            }
            //查询策略
            List<Map<String, Object>> queryStrategys = (List<Map<String, Object>>) func.get("queryStrategys");
            if (queryStrategys != null && queryStrategys.size() > 0) {
                batchInsert(queryStrategys, "JE_CORE_QUERYSTRATEGY");
            }
            //高级查询
            List<Map<String, Object>> groupquerys = (List<Map<String, Object>>) func.get("groupquerys");
            if (groupquerys != null && groupquerys.size() > 0) {
                batchInsert(groupquerys, "JE_CORE_GROUPQUERY");
            }
            //子功能
            List<Map<String, Object>> childs = (List<Map<String, Object>>) func.get("childs");
            if (childs != null && childs.size() > 0) {
                batchInsert(childs, "JE_CORE_FUNCRELATION");
                for (Map<String, Object> map : childs) {
                    JSONObject childsValue = (JSONObject) map.get("values");
                    if (childsValue.containsKey("associations")) {
                        List<Map<String, Object>> associations = (List<Map<String, Object>>) childsValue.get("associations");
                        if (associations != null && associations.size() > 0) {
                            batchInsert(associations, "JE_CORE_ASSOCIATIONFIELD");
                        }
                    }
                }
            }
            //权限
            FuncDataPermVo funcDataPermVo = JSON.parseObject(func.getStr("funcPerm"), FuncDataPermVo.class);
            installFuncDataPerm(funcDataPermVo, func.getStr("FUNCINFO_FUNCCODE"), func.getStr("JE_CORE_FUNCINFO_ID"));
            //目录
            List<Map<String, Object>> parentList = (List<Map<String, Object>>) func.get("parentList");
            insertOrUpdate(parentList, "JE_CORE_FUNCINFO", "JE_CORE_FUNCINFO_ID");
            //功能、子功能、按钮授权
            if (func.getStr("FUNCINFO_FUNCTYPE").equals(FuncTypeEnum.FUNC.getValue()) ||
                    func.getStr("FUNCINFO_FUNCTYPE").equals(FuncTypeEnum.TREE.getValue()) ||
                    func.getStr("FUNCINFO_FUNCTYPE").equals(FuncTypeEnum.VIEW.getValue())) {
                permissionRpcService.quickGranFunc(func.getStr("SY_PRODUCT_ID"), func.getStr("FUNCINFO_FUNCCODE"));
                //清缓存
                metaStaticizeService.removeCache(func.getStr("FUNCINFO_FUNCCODE"), func.getStr("SY_PRODUCT_CODE"));
            }
            //记录升级日志
            upgradelogRpcService.saveUpgradelog(upgradeInstallId,
                    UpgradeResourcesEnum.FUNC.getType(), UpgradeResourcesEnum.FUNC.getName(),
                    func.getStr("FUNCINFO_FUNCNAME"), func.getStr("FUNCINFO_FUNCCODE"));

        }
        return null;
    }

    private void deleteChildTableDataByFuncId(String funcInfoId) {
        //删除高级查询
        metaService.delete("JE_CORE_GROUPQUERY",
                ConditionsWrapper.builder().eq("GROUPQUERY_GNID", funcInfoId));
        //列表字段
        metaService.delete("JE_CORE_RESOURCECOLUMN",
                ConditionsWrapper.builder().eq("RESOURCECOLUMN_FUNCINFO_ID", funcInfoId));
        //表单字段
        metaService.delete("JE_CORE_RESOURCEFIELD",
                ConditionsWrapper.builder().eq("RESOURCEFIELD_FUNCINFO_ID", funcInfoId));
        //按钮
        metaService.delete("JE_CORE_RESOURCEBUTTON",
                ConditionsWrapper.builder().eq("RESOURCEBUTTON_FUNCINFO_ID", funcInfoId));
        //查询策略
        metaService.delete("JE_CORE_QUERYSTRATEGY",
                ConditionsWrapper.builder().eq("QUERYSTRATEGY_FUNCINFO_ID", funcInfoId));
        //子功能
        metaService.delete("JE_CORE_FUNCRELATION",
                ConditionsWrapper.builder().eq("FUNCRELATION_FUNCINFO_ID", funcInfoId));


    }

    private void installFuncDataPerm(FuncDataPermVo funcDataPermVo, String funcCode, String funcId) {
        if (funcDataPermVo != null) {
            //清空数据
            metaService.delete("JE_CORE_FUNCPERM", ConditionsWrapper.builder().eq("FUNCPERM_FUNCINFO_ID", funcId));
            String[] authTypeArr = {FuncDataPermCons.FAST_AUTH, FuncDataPermCons.FIELD_AUTH,
                    FuncDataPermCons.DICTIONARY_AUTH, FuncDataPermCons.ROLESQL_AUTH, FuncDataPermCons.SQL_AUTH, FuncDataPermCons.CONTROL_FIELD};
            for (String authType : authTypeArr) {
                DynaBean dynaBean = new DynaBean("JE_CORE_FUNCPERM", true);
                dynaBean.setStr("FUNCPERM_FUNCINFO_CODE", funcCode);
                dynaBean.setStr("FUNCPERM_FUNCINFO_ID", funcId);
                dynaBean.setStr("FUNCPERM_TYPE", authType);
                if (authType.equals(FuncDataPermCons.FAST_AUTH)) {
                    FastAuthVo fastAuthVo = funcDataPermVo.getFastAuthVo();
                    if (fastAuthVo != null) {
                        dynaBean.setStr("FUNCPERM_ON_OFF", fastAuthVo.getAuthOnOff());
                        dynaBean.setStr("FUNCPERM_CONFIG", JSON.toJSONString(fastAuthVo));
                    }
                }
                if (authType.equals(FuncDataPermCons.FIELD_AUTH)) {
                    FieldAuthVo fieldAuthVo = funcDataPermVo.getFieldAuthVo();
                    if (fieldAuthVo != null) {
                        dynaBean.setStr("FUNCPERM_ON_OFF", fieldAuthVo.getAuthOnOff());
                        dynaBean.setStr("FUNCPERM_CONFIG", JSON.toJSONString(fieldAuthVo));
                    }
                }
                if (authType.equals(FuncDataPermCons.DICTIONARY_AUTH)) {
                    DictionaryAuthVo dictionaryAuthVo = funcDataPermVo.getDictionaryAuthVo();
                    if (dictionaryAuthVo != null) {
                        dynaBean.setStr("FUNCPERM_ON_OFF", dictionaryAuthVo.getAuthOnOff());
                        dynaBean.setStr("FUNCPERM_CONFIG", JSON.toJSONString(dictionaryAuthVo));
                    }
                }

                if (authType.equals(FuncDataPermCons.ROLESQL_AUTH)) {
                    RoleSqlAuthVo roleSqlAuthVo = funcDataPermVo.getRoleSqlAuthVo();
                    if (roleSqlAuthVo != null) {
                        dynaBean.setStr("FUNCPERM_ON_OFF", roleSqlAuthVo.getAuthOnOff());
                        dynaBean.setStr("FUNCPERM_CONFIG", JSON.toJSONString(roleSqlAuthVo));
                    }
                }

                if (authType.equals(FuncDataPermCons.SQL_AUTH)) {
                    String sql = funcDataPermVo.getSql();
                    if (StringUtil.isNotEmpty(sql)) {
                        dynaBean.setStr("FUNCPERM_CONFIG", sql);
                    }
                }

                if (authType.equals(FuncDataPermCons.CONTROL_FIELD)) {
                    ControlFieldAuthVo controlFieldAuthVo = funcDataPermVo.getControlFieldAuthVo();
                    if (controlFieldAuthVo != null) {
                        dynaBean.setStr("FUNCPERM_CONFIG", JSON.toJSONString(controlFieldAuthVo));
                    }
                }
                String funcpermConfig = dynaBean.getStr("FUNCPERM_CONFIG");
                if (StringUtil.isNotEmpty(funcpermConfig)) {
                    funcPermService.doUpdatePerm(dynaBean);
                }
            }
        }
    }

    @Transactional
    public String installTable(String upgradeInstallId, List<DynaBean> tableBeanList, String productCode) {
        UpgradeModulePackageRpcService upgradeModulePackageRpcService = null;
        if (!PRODUCT_CORE_META.equals(productCode)) {
            upgradeModulePackageRpcService = RpcSchemaFactory.getRemoteProvierClazz(productCode,
                    "upgradeModulePackageRpcService", UpgradeModulePackageRpcService.class);
        }


        for (DynaBean table : buildInstallTablesList(tableBeanList)) {
            boolean isInsert = true;
            table.table("JE_CORE_RESOURCETABLE");
            String pkValue = table.getStr("JE_CORE_RESOURCETABLE_ID");
            String resourcetableTablecode = table.getStr("RESOURCETABLE_TABLECODE");
            DynaBean tableDB = metaService.selectOne("JE_CORE_RESOURCETABLE",
                    ConditionsWrapper.builder()
                            .apply(" RESOURCETABLE_TABLECODE={0} or JE_CORE_RESOURCETABLE_ID={1}", resourcetableTablecode, pkValue));
            List<DynaBean> localColumns = new ArrayList<>();

            /**
             * 目前树形表都是内联外键，导致删除父级时子级全部自动删除
             * 1.现修改为资源表在目标系统若存在，则更新,不会删除
             */

            if (tableDB != null) {
                localColumns = metaService.select("JE_CORE_TABLECOLUMN",
                        ConditionsWrapper.builder().eq("TABLECOLUMN_RESOURCETABLE_ID", pkValue));
                //删除子表信息
                deleteChildTableDataByTableId(tableDB.getStr("JE_CORE_RESOURCETABLE_ID"));

                //更新资源表信息
                commonService.buildModelModifyInfo(table);
                metaService.update(table, ConditionsWrapper.builder().eq("RESOURCETABLE_TABLECODE", resourcetableTablecode));
                isInsert = false;
            } else {
                //资源表
                commonService.buildModelCreateInfo(table);
                metaService.insert(table);
            }
            logger.info("------------添加表");


            List<String> sqlList = new ArrayList<>();
            if (Arrays.stream(UPDATE_TABLE_TYPE).anyMatch(table.getStr("RESOURCETABLE_TYPE")::equals)) {
                //列,不能删除字段，只能增加字段和修改字段
                logger.info("------------获取表列信息");
                List<Map<String, Object>> tableColumns = (List<Map<String, Object>>) table.get("tableColumns");
                if (tableColumns != null && tableColumns.size() > 0) {
                    if (localColumns.size() > 0) {
                        metaService.insertBatch(buildNewColumns(localColumns, tableColumns));
                    } else {
                        batchInsert(tableColumns, "JE_CORE_TABLECOLUMN");
                    }
                }
                logger.info("------------获取表键信息");
                //键
                List<Map<String, Object>> tableKeys = (List<Map<String, Object>>) table.get("tableKeys");
                if (tableKeys != null && tableKeys.size() > 0) {
                    batchInsert(tableKeys, "JE_CORE_TABLEKEY");
                }
                logger.info("------------获取表索引信息");
                //索引
                List<Map<String, Object>> tableIndexs = (List<Map<String, Object>>) table.get("tableIndexs");
                if (tableIndexs != null && tableIndexs.size() > 0) {
                    batchInsert(tableIndexs, "JE_CORE_TABLEINDEX");
                }
                logger.info("------------应用表");
                //应用表
                //应用前校验
                String result = tableService.checkTableForApply(pkValue);
                if (StringUtil.isNotEmpty(result)) {
                    throw new PlatformException(result, PlatformExceptionEnum.UNKOWN_ERROR);
                }
                if (isInsert) {
                    sqlList = tableService.generateCreateDDL(pkValue);
                    if (PRODUCT_CORE_META.equals(table.getStr("SY_PRODUCT_CODE"))) {
                        executeSql(sqlList);
                    } else {
                        upgradeModulePackageRpcService.executeSql(sqlList);
                    }
                    tableService.afterTableCreated(pkValue);
                } else {
                    logger.info("------------修改表");
                    List<DbModel> dbModels = new ArrayList<>();
                    if (PRODUCT_CORE_META.equals(table.getStr("SY_PRODUCT_CODE"))) {
                        dbModels = loadTableColumnBySql(table.getStr("RESOURCETABLE_TABLECODE"));
                        sqlList = tableService.generateUpdateDDL(pkValue, dbModels);
                        executeSql(sqlList);
                    } else {
                        dbModels = upgradeModulePackageRpcService.loadTableColumnBySql(table.getStr("RESOURCETABLE_TABLECODE"));
                        sqlList = tableService.generateUpdateDDL(pkValue, dbModels);
                        upgradeModulePackageRpcService.executeSql(sqlList);
                    }
                    tableService.afterTableUpdated(pkValue);
                }
            }


            if (TableTypeEnum.VIEW.getValue().equals(table.getStr("RESOURCETABLE_TYPE"))) {
                //列
                List<Map<String, Object>> tableColumns = (List<Map<String, Object>>) table.get("tableColumns");
                if (tableColumns != null && tableColumns.size() > 0) {
                    batchInsert(tableColumns, "JE_CORE_TABLECOLUMN");
                }
                //键
                List<Map<String, Object>> tableKeys = (List<Map<String, Object>>) table.get("tableKeys");
                if (tableKeys != null && tableKeys.size() > 0) {
                    batchInsert(tableKeys, "JE_CORE_TABLEKEY");
                }
                //视图关联关系
                List<Map<String, Object>> viewCascades = (List<Map<String, Object>>) table.get("viewCascades");
                if (viewCascades != null && viewCascades.size() > 0) {
                    batchInsert(viewCascades, "JE_CORE_VIEWCASCADE");
                }
                //创建视图
                String sql = table.getStr("RESOURCETABLE_SQL");
                if (sql.startsWith("CREATE VIEW")) {
                    sql = sql.replace("CREATE VIEW", "CREATE OR REPLACE VIEW");
                }
                sqlList.add(sql);
                if (PRODUCT_CORE_META.equals(table.getStr("SY_PRODUCT_CODE"))) {
                    executeSql(sqlList);
                } else {
                    upgradeModulePackageRpcService.executeSql(sqlList);
                }
            }
            //目录
            List<Map<String, Object>> parentList = (List<Map<String, Object>>) table.get("parentList");
            logger.info("------------修改表上级信息");
            insertOrUpdate(parentList, "JE_CORE_RESOURCETABLE", "JE_CORE_RESOURCETABLE_ID");
            logger.info("------------记录日志");
            //记录日志
            upgradelogRpcService.saveUpgradelog(upgradeInstallId,
                    UpgradeResourcesEnum.TABLE.getType(), UpgradeResourcesEnum.TABLE.getName(),
                    table.getStr("RESOURCETABLE_TABLENAME"), table.getStr("RESOURCETABLE_TABLECODE"));
        }
        return null;
    }

    private void deleteChildTableDataByTableId(String tableId) {
        //列
        metaService.delete("JE_CORE_TABLECOLUMN",
                ConditionsWrapper.builder().eq("TABLECOLUMN_RESOURCETABLE_ID", tableId));
        //键
        metaService.delete("JE_CORE_TABLEKEY",
                ConditionsWrapper.builder().eq("TABLEKEY_RESOURCETABLE_ID", tableId));
        //索引
        metaService.delete("JE_CORE_TABLEINDEX",
                ConditionsWrapper.builder().eq("TABLEINDEX_RESOURCETABLE_ID", tableId));

        //删除视图的关联关系
        metaService.delete("JE_CORE_VIEWCASCADE",
                ConditionsWrapper.builder().eq("JE_CORE_RESOURCETABLE_ID", tableId));
    }

    /**
     * 格式化 排序，表或者模块放上面，视图放下面  先升级表，再升级视图
     *
     * @param tableBeanList
     * @return
     */
    private List<DynaBean> buildInstallTablesList(List<DynaBean> tableBeanList) {
        List<DynaBean> tableAndModel = new ArrayList<>();
        List<DynaBean> views = new ArrayList<>();
        for (DynaBean table : tableBeanList) {
            if (!TableTypeEnum.VIEW.getValue().equals(table.getStr("RESOURCETABLE_TYPE"))) {
                tableAndModel.add(table);
            } else {
                views.add(table);
            }
        }

        List<DynaBean> resultList = new ArrayList<>();
        for (DynaBean dynaBean : tableAndModel) {
            resultList.add(dynaBean);
        }
        for (DynaBean dynaBean : views) {
            resultList.add(dynaBean);
        }
        return resultList;
    }

    private List<DynaBean> buildNewColumns(List<DynaBean> localColumns, List<Map<String, Object>> tableColumns) {
        List<DynaBean> columns = new ArrayList<>();
        if (localColumns != null && localColumns.size() > 0) {
            Map<String, Object> map = tableColumns.stream().collect(Collectors.toMap(p -> getValuesColumn(p, "TABLECOLUMN_CODE"), p -> p));
            Iterator<DynaBean> it_b = localColumns.iterator();
            while (it_b.hasNext()) {
                DynaBean dynaBean = it_b.next();
                if (map.containsKey(dynaBean.getStr("TABLECOLUMN_CODE"))) {
                    Map<String, Object> valuesMap = (Map<String, Object>) map.get(dynaBean.getStr("TABLECOLUMN_CODE"));
                    columns.add(buildColumn(valuesMap));
                    it_b.remove();
                    map.remove(dynaBean.getStr("TABLECOLUMN_CODE"));
                }
            }
            if (localColumns != null && localColumns.size() > 0) {
                columns.addAll(localColumns);
            }
            if (map != null && map.size() > 0) {
                for (Map.Entry<String, Object> entry : map.entrySet()) {
                    Map<String, Object> mapValue = (Map<String, Object>) entry.getValue();
                    columns.add(buildColumn(mapValue));
                }
            }
        }
        return columns;
    }

    public String getValuesColumn(Map<String, Object> map, String column) {
        Map<String, Object> values = (Map<String, Object>) map.get("values");
        return values.get(column).toString();
    }

    private DynaBean buildColumn(Map<String, Object> values) {
        DynaBean dynaBean = new DynaBean();
        dynaBean.setValues((Map<String, Object>) values.get("values"));
        dynaBean.table("JE_CORE_TABLECOLUMN");
        commonService.buildModelCreateInfo(dynaBean);
        return dynaBean;
    }

}
